﻿using System;
using Xunit;

// ReSharper disable TryCastAlwaysSucceeds
// ReSharper disable RedundantCast
// ReSharper disable RedundantTypeArgumentsOfMethod

namespace Viyi.Util.Test.Utils
{
    public class TestObjectUtil
    {
        [Fact(DisplayName = "允许值类型AS")]
        public void TestAsStruct()
        {
            Assert.Equal((short) 123, ((object) (short) 123).As<short>(0));
            Assert.Equal("hello", ((object) "hello").As<string>(string.Empty));
        }

        [Fact(DisplayName = "As失败返回默认值")]
        public void TestInvalidCast()
        {
            Assert.Equal(-1, ((object) 123L).As<int>(-1));
            Assert.Equal(-2L, ((object) 1234).As<long>(-2L));
            Assert.Equal(null, new object().As<string>());
        }

        [Fact(DisplayName = "对类类型AS()应该和as操作符结果相同")]
        public void TestClassCast()
        {
            Sub sub = new Sub();
            Super super = sub;
            Super super2 = new Super();

            Assert.Equal(sub as Super, sub.As<Super>());
            Assert.Equal(super as Sub, super.As<Sub>());
            Assert.Equal(super2 as Sub, super2.As<Sub>());
        }

        private class Super { }
        private sealed class Sub : Super { }

        // 由于是直接封装的 Convert.ChangeType，所以成功的情况不用测试
        [Fact(DisplayName = "Convert To 失败返回默认值")]
        public void ConvertFail()
        {
            Assert.Equal(DateTime.MinValue, ObjectUtil.ConvertTo<DateTime>("abcdef"));
        }

        [Fact(DisplayName = "ObjectUtil.ToInt32为代表测试ToXxxx")]
        public void ConvertInt32()
        {
            Assert.Equal(4567, ObjectUtil.ConvertTo<int>(4567L));
            Assert.Equal(1579, ObjectUtil.ConvertTo<int>("1579"));
            Assert.Equal(0, ObjectUtil.ConvertTo<int>("xyz"));
            Assert.Equal(-3, ObjectUtil.ConvertTo<int>("xyz", -3));
        }
    }
}
